package com.parkLot.spring.socket;

import com.parkLot.spring.service.ParkPointService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/*
 * 通讯协议
 * 规范：状态码+编号
 * 例子: ff8e -->打开编号为8e的LED, 8e为十六进制，根据需要可以自行转化成十进制
 * 状态码：
 * 2f --> 开
 * 2e --> 关
 * 2d --> 查询状态
 * 1c --> 返回状态
 * 1b --> 返回操作结果
 * 1a --> 操作有错误
 */
@Component
public class SocketServerPointHex {

	@Autowired
	private ParkPointService parkPointService;

	private static int port = 2021;
	private Socket socket = null;
	private static OutputStream espOs = null;

	//创建构造器
	public SocketServerPointHex(int serverPort) {
		port = serverPort;
	}

	public SocketServerPointHex() {
		//port = serverPort;
		super();
	}

	//开启连接
	public void startSocket() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					ServerSocket serverSocket = new ServerSocket(port);
					System.out.println("ServerSocket创建成功！，当前目标端口："+port);

					System.out.println("服务器启动成功，等待连接~");
					Socket socket = null;
					//循环监听
					while(true) {
						//accpet函数会产生一个阻塞，直到有客户端连接
						socket = serverSocket.accept();
						if(socket != null) {
							System.out.println("连接成功");
							//获取客户端信息
							InetAddress address = socket.getInetAddress();
							System.out.println("服务器IP："+address.getLocalHost()+"端口号："+socket.getPort());
							//开启多线程，针对每个连接，开启一个线程处理请求
							clientRead(socket);
						}else {
							System.out.println("服务器启动成功，等待连接~");
						}
					}
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
					System.out.println("ServerSocket创建失败，当前目标端口："+port);
				}
			}
		}).start();
	}

	//读取数据的操作
	private void clientRead(Socket cs) {
		// TODO Auto-generated method stub
		new Thread(new Runnable() {
			InputStream is = null;
			OutputStream os = null;

			@Override
			public void run() {
				//System.out.println("当前线程："+Thread.currentThread().getName());
				//System.out.println("监听端口："+cs.getPort());
				try {
					if(cs != null) {
						is = cs.getInputStream();
						os = cs.getOutputStream();
						espOs = os;
					}
					while(cs != null && cs.isConnected()) {
						int buffer_length = is.available();
						if (buffer_length > 0) {
							System.out.println(Thread.currentThread().getName()+" 缓冲区大小"+buffer_length);
							//使用字节数组读取数据
							byte[] bytes = new byte[buffer_length];
							if(is.read(bytes) == -1) {
								System.out.println("读取失败");
								cs.close();
							}
							System.out.println(bytes[0]);
							if(bytes[0] == 0x1c) {
								//返回状态
								String info = byteArrayToHexStr(bytes);
								String address = "0x" + info.substring(2);
								System.out.println("返回状态："+address);
								parkPointService.getPointByAddress(address);
							}else if(bytes[0] == 0x1b) {
								//操作结果
								String info = byteArrayToHexStr(bytes);
								System.out.println("操作结果："+info);

							}else {
								String info = byteArrayToHexStr(bytes);
								System.out.println("异常操作："+info);
								//sendToESP8266("3eda2f");
							}
						}
					}
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
		}).start();
	}

	public SocketServerPointHex(Socket socket) {
		super();
		this.socket = socket;
	}

	public void sendToESP8266(String info) {
		try {
			byte[] cmd = hexStrToByteArray(info);
			if(espOs != null) {
				espOs.write(cmd);
				espOs.flush();
			}
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("操作失败");
		}

	}

	//将字节数组转化成字符串的操作
	public static String byteArrayToHexStr(byte[] byteArray) {
		if (byteArray == null){
			return null;
		}
		char[] hexArray = "0123456789ABCDEF".toCharArray();
		char[] hexChars = new char[byteArray.length * 2];
		for (int j = 0; j < byteArray.length; j++) {
			int v = byteArray[j] & 0xFF;
			hexChars[j * 2] = hexArray[v >>> 4];
			hexChars[j * 2 + 1] = hexArray[v & 0x0F];
		}
		return new String(hexChars);
	}

	//字符串转化成十六进制
	public static byte[] hexStrToByteArray(String str)
	{
		if (str == null) {
			return null;
		}
		if (str.length() == 0) {
			return new byte[0];
		}
		byte[] byteArray = new byte[str.length() / 2];
		for (int i = 0; i < byteArray.length; i++){
			String subStr = str.substring(2 * i, 2 * i + 2);
			byteArray[i] = ((byte)Integer.parseInt(subStr, 16));
		}
		return byteArray;
	}
}
